package middleware

import (
	"context"
	"fmt"
	"gitee.com/mootok/mootok/src/constant/strings"
	redis2 "gitee.com/mootok/mootok/src/constant/strings/redis"
	"gitee.com/mootok/mootok/src/services/user"
	"gitee.com/mootok/mootok/src/web/common/response"
	middleware_oapi "github.com/deepmap/oapi-codegen/pkg/gin-middleware"
	"github.com/getkin/kin-openapi/openapi3filter"
	"github.com/gin-gonic/gin"
	"net/http"
	"strconv"
)

var userService user.Service

func AuthenticationFuncMiddleWare(ctx context.Context, input *openapi3filter.AuthenticationInput) error {
	//get token from cookie
	validationInput := input.RequestValidationInput
	request := validationInput.Request
	cookie, err := request.Cookie(strings.UserLoginCookie)

	if err != nil {
		return fmt.Errorf("read token failed %s", err)
	}

	if cookie == nil {
		return fmt.Errorf("token cookie is empty")
	}

	//get userContext from redis
	ginContext := middleware_oapi.GetGinContext(ctx)
	value, err := userService.GetUserIdByToken(ginContext, cookie.Value)

	if err != nil {
		return fmt.Errorf("token has expired %s", err)
	}

	//fix userContext type
	userContext, err := strconv.Atoi(value)

	if err != nil {
		return fmt.Errorf("internal service error %s", err)
	}

	//put userContext into context
	ginContext.Set(strings.UserLoginContext, userContext)

	//renew user token
	err = userService.ReNewUserLoginExpiredTime(ginContext, cookie.Value)
	if err != nil {
		return fmt.Errorf("internal server error %s", err)
	}
	ginContext.SetCookie(strings.UserLoginCookie, cookie.Value, redis2.UserLoginTokenExpireTime, "", "", false, true)
	return nil
}

func AuthenticationErrorHandlerMiddleWare(c *gin.Context, message string, statusCode int) {
	if statusCode == http.StatusNotFound {
		//404
		response.FailWithMsg(c, http.StatusNotFound, strings.NotFoundErrorCode, strings.NotFoundError)
		return
	}
	response.FailWithMsg(c, statusCode, statusCode, message)
}
